package edu.hawaii.halealohacli.command;

import org.wattdepot.client.ResourceNotFoundException;
import org.wattdepot.client.WattDepotClient;

/**
 * Periodically reports the current power consumption of a given source until
 * the user ends the command.
 * <p>
 * Usage: monitor-power [tower | lounge] [interval]
 * <p> 
 * This command prints out a timestamp and the current power for [tower | lounge]
 * every [interval] seconds. [interval] is an optional argument and
 * defaults to 10 seconds. Pressing Enter stops this monitoring process and 
 * returns the user to the command loop.
 * 
 * @author Jeffrey M. Beck
 * @author Zach Tomaszewski
 */
public class MonitorPower extends RepeatedCommand implements Command {

  /** How frequently this command executes if an interval is not specified. */
  public static final int DEFAULT_INTERVAL = 10;  
  
  private static final String HEADER_FORMAT = "%-20s %s %n";
  private static final String ROW_FORMAT = " %-19tT %10.2f"; //time and power
  
  private WattDepotClient client = null; 
  private String sourceName = null;
  private int interval = DEFAULT_INTERVAL;
  private String error = null;  //if set, then then command is invalid

  /**
   * Expects an argument array containing the name of the source to find 
   * current power for and (optionally) a check-frequency interval in seconds.
   * 
   * @param args A string array containing the two arguments.
   * @param client The WattDepot client to collect this data from.
   */
  @Override
  public void initialize(String[] args, WattDepotClient client) {
    this.client = client;       
    if (args != null && (args.length == 1 || args.length == 2)) {
      //valid number of args
      this.sourceName = args[0];
      if (args.length == 2) {
        try {
          this.interval = Integer.parseInt(args[1]);
        }
        catch (NumberFormatException e) { 
          this.interval = -1;
        }
      }
      
      //now error-checking
      if (this.client == null || !this.client.isHealthy()) {
        error = "Invalid WattDepot client";
      }
      else if (this.sourceName == null) { 
        error = "Source name not given.";
      }
      else if (this.interval <= 0) {
        error = "Interval must be a positive integer.";
      }  
    }
    else {
      error = "Invalid arguments for " + getCommandName() + ".\n" + getCommandUsage();      
    }  
  }

  /**
   * Prints the returned value from getResults to System.out.
   */
  @Override
  public void execute() {
    if (error == null) { 
      //command is valid, so print header and start repeating for each data line
      System.out.println("Querying " + this.sourceName + 
          " for current power every " + this.interval + " seconds. ");
      System.out.println("(Press Enter to stop.)");
      System.out.println();
      
      System.out.printf(HEADER_FORMAT, "Most Recent Data", "Power Consumption (kW)");
      this.execute(this.interval);
    }
    else {
      System.out.println(error); 
    }
  }

  @Override
  public void doTask() {
    System.out.println(this.getResults());    
  }

  /**
   * Queries the WattDepot server for current power consumption, returning a 
   * single string containing the latest data timestamp and power consumption.
   * If there was an error, will return an error message instead. 
   * 
   * @return The message to display to the user.
   */
  public String getResults() {
    if (error != null) {
      return error;
    }
    
    //reused CurrentPower object to get current power data
    CurrentPower cp = new CurrentPower();
    cp.initialize(new String[]{sourceName}, client);
    try {
      CurrentPower.Data data = cp.getCurrentPower();
      return String.format(ROW_FORMAT, data.getTimestamp(), data.getPower() / 1000);
      
    }
    catch (ResourceNotFoundException e) {
      return sourceName + " is not a valid source name.";
    }
    catch (Exception e) {
      return "Sensor data could not be retrieved for " + sourceName;
    }
  }

  @Override
  public String getCommandName() {
    return "monitor-power";
  }

  @Override
  public String getCommandUsage() {
    return getCommandName()
        + " [tower | lounge] [interval]\n"
        + "Prints a timestamp and current power being consumed every [interval] seconds."
        + "\nIf no interval is specified, 10 seconds is the default."
        + "\nPress enter to stop monitoring and return to the command loop.\n\n";
  }
  
}
